home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
301-325
/
disk_313
/
uucp
/
uucp1.lzh
/
src
/
sendmail
/
sendmail.c
< prev
Wrap
C/C++ Source or Header
|
1990-01-25
|
22KB
|
1,043 lines
/*
* SENDMAIL / RMAIL
*
* (C) Copyright 1989-1990 by Matthew Dillon, All Rights Reserved.
*
* SENDMAIL <file -f from -t to -s subject -c cc -b bcc -r
* RMAIL user
*
* Example: Sendmail <datafile -froot
*
* From: line is automatically added but can be overriden by a From:
* header in the file. stdin is made up of a list of headers, a blank
* line, and then data until EOF.
*
* the -r option tells sendmail that this is incomming mail.
* If av[0] begins with an 'r' for RMail instead of an 's' for
* Sendmail, then the rmail argument format is used (rmail user),
* as well as forcing -r.
*/
#include <exec/types.h>
#include <exec/lists.h>
#include <proto/all.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <log.h>
#include <config.h>
#include <time.h>
#include <pwd.h>
#include <string.h>
#include "/version.h"
#define RCVR_UUCP 1
#define RCVR_SENDMAIL 2
IDENT(".03");
typedef struct List LIST;
typedef struct Node NODE;
char *UserName;
char *NodeName;
char *DomainName;
char *TimeZoneName; /* All caps, ex: PST */
char *DefaultNode; /* for addr formats we don't understand */
LIST RecvList; /* Received: */
LIST FromList; /* last one rules */
LIST ToList; /* To: */
LIST CcList; /* Cc: */
LIST BccList; /* Bcc: */
LIST XccList; /* list of actual mail to be sent */
LIST SubjList; /* Subject: */
LIST HdrList; /* other headers not specifically parsed */
char ScrBuf[1024];
char ScrBuf2[1024];
char TempFileBuf[256];
int Seq; /* UUCP sequence no */
char ROpt; /* Receive-Mail flag */
static char OrigFromLine[512];
static char FromLine[512]; /* 'From ' line, if ROpt */
char *TmpFileName();
char *atime();
void PostPend();
void MakeToFixNode();
void MakeToAddrNode();
void ToFixup();
void FromFixup();
void DumpHeaderInfo();
void DumpHeader();
void DumpCombineHeader();
void IntegrateHeader();
void Usage();
FILE *SendMailTo();
FILE *OneMailTo();
FILE *OneMailToUUCP();
FILE *OneMailToUser();
FILE *OneMailToFile();
FILE *OneMailToPipe();
NODE *FindHeader();
NODE *MakeNode();
CXBRK()
{
return(0);
}
void
Usage()
{
printf(
"Sendmail -f user [-t address -c address -b address -s subject -r]\n"
"RMail user\n"
);
}
void
main(ac, av)
char *av[];
{
short isRMail = 0;
short isSendMail = 1;
FILE *fi;
NewList(&RecvList);
NewList(&FromList);
NewList(&ToList);
NewList(&CcList);
NewList(&BccList);
NewList(&XccList);
NewList(&SubjList);
NewList(&HdrList);
UserName = FindConfig("UserName");
if (UserName == NULL) {
puts("Sendmail: UserName not in UULIB:Config!");
exit(1);
}
NodeName = FindConfig("NodeName");
if (NodeName == NULL) {
puts("Sendmail: NodeName not in UULIB:Config!");
exit(1);
}
DomainName = FindConfig("DomainName");
if (DomainName == NULL) {
puts("Sendmail: DomainName not in UULIB:Config! using .UUCP");
DomainName = ".UUCP";
}
DefaultNode = FindConfig("DefaultNode");
TimeZoneName = FindConfig("TimeZone");
LoadAliases();
{
char *ptr = av[0] + strlen(av[0]);
/*
* Skip path
*/
while (ptr >= av[0] && *ptr != ':' && *ptr != '/')
--ptr;
++ptr;
if (*ptr == 'r' || *ptr == 'R') {
isRMail = 1;
isSendMail = 0;
}
}
if (isRMail) {
char *addr = (ac == 2) ? av[1] : "Mailer-Daemon";
MakeNode(&BccList, addr);
UserName = "postmaster"; /* XXX */
ROpt = 1; /* no header processing */
}
if (isSendMail) {
short i;
char *arg;
for (i = 1; i < ac; ++i) {
arg = av[i];
if (*arg != '-')
Usage();
switch(arg[1]) {
case 'f':
UserName = av[i+1];
sprintf(ScrBuf, "%s@%s%s", av[i+1], NodeName, DomainName);
MakeNode(&FromList, ScrBuf);
++i;
break;
case 't':
MakeNode(&ToList, av[++i]);
break;
case 'c':
MakeNode(&CcList, av[++i]);
break;
case 'b':
MakeNode(&BccList, av[++i]);
break;
case 's':
MakeNode(&SubjList, av[++i]);
break;
case 'r':
++ROpt;
break;
default:
Usage();
}
}
}
/*
* Read headers from input file. Headers are not necessarily
* contained on a single line. Maximum 4096 chars per header.
*/
if (ROpt) {
fgets(ScrBuf, sizeof(ScrBuf), stdin);
strcpy(OrigFromLine, ScrBuf);
if (strncmp(ScrBuf, "From ", 5) != 0) {
ulog(-1, "Receive mail, expected 'From ', got %s", ScrBuf);
}
strcpy(FromLine, "From ");
PostPend(ScrBuf + 5, 1);
while (fgets(ScrBuf, sizeof(ScrBuf), stdin) && strncmp(ScrBuf, ">From ", 6) == 0) {
strcpy(OrigFromLine, ScrBuf + 1);
PostPend(ScrBuf + 6, 1);
}
strcpy(ScrBuf2, OrigFromLine + 5);
PostPend(ScrBuf2, 0);
} else {
ScrBuf[0] = '\n';
fgets(ScrBuf, sizeof(ScrBuf), stdin);
}
{
static char Hdr[4096];
short i = 0; /* index into Hdr */
while (ScrBuf[0] != '\n') {
char *ptr = ScrBuf;
while (*ptr && *ptr != ' ' && *ptr != 9 && *ptr != ':')
++ptr;
if (*ptr == ':') { /* found new header */
if (i) /* Dump old header */
IntegrateHeader(Hdr, i);
strcpy(Hdr, ScrBuf);
i = strlen(Hdr);
} else { /* append to existing header */
if (i == 0)
puts("Expected a Header!");
strcpy(Hdr + i, ScrBuf);
i = i + strlen(Hdr + i);
}
if (fgets(ScrBuf, sizeof(ScrBuf), stdin) == NULL)
ScrBuf[0] = '\n';
}
if (i)
IntegrateHeader(Hdr, i);
if (ScrBuf[0] != '\n') {
puts("sendmail: no mail");
exit(1);
}
}
/*
* Parse & fixup each To:, Cc:, and Bcc: field.
*
* From: we add the personal info arg from the password file
* To: we expand any aliases
*/
if (ROpt == 0)
FromFixup(&FromList);
if (ROpt) {
ToFixup(&BccList);
} else {
ToFixup(&ToList);
ToFixup(&CcList);
ToFixup(&BccList);
}
/*
* If no Subject: field add a dummy one
*/
if (EmptyList(&SubjList))
MakeNode(&SubjList, "");
if (EmptyList(&FromList)) {
sprintf(ScrBuf, "%s@%s%s", UserName, NodeName, DomainName);
MakeNode(&FromList, ScrBuf);
}
fi = SendMailTo(&XccList, stdin);
if (fi && fi != stdin)
fclose(fi);
if (TempFileBuf[0])
remove(TempFileBuf);
UnLockFiles();
}
/*
* Strips string and creates named node which is appended to the
* given list.
*/
NODE *
MakeNode(list, str)
LIST *list;
char *str;
{
NODE *node;
char *ptr;
while (*str == ' ' || *str == 9)
++str;
for (ptr = str + strlen(str); ptr >= str && (*ptr == ' ' || *ptr == 9); --ptr);
++ptr;
*ptr = 0;
node = malloc(sizeof(NODE) + strlen(str) + 1);
node->ln_Name = (char *)(node + 1);
strcpy(node->ln_Name, str);
AddTail(list, node);
return(node);
}
/*
*
*/
void
MakeToFixNode(list, str, send)
LIST *list;
char *str;
char *send;
{
char *ptr;
short len;
short c;
void fixCallBack();
while (str < send && (*str == ' ' || *str == 9))
++str;
for (ptr = send - 1; ptr >= str && (*ptr == ' ' || *ptr == 9); --ptr);
++ptr;
len = ptr - str;
if (len < 0)
return;
/*
* str[0..len-1]
*/
c = str[len];
str[len] = 0;
if (ROpt) { /* disallow remote asking for special options */
ulog(-1, "Received mail for %s", str);
if (str[0] == '>' || str[0] == '<' || str[0] == '|' || str[0] == ':' || str[0] == '/') {
ulog(-1, "SendMail, bad user %s", str);
return;
}
}
{
NODE *node = malloc(sizeof(NODE) + strlen(str) + 1);
node->ln_Name = (char *)(node + 1);
strcpy(node->ln_Name, str);
AddTail(list, node);
}
UserAliasList(str, fixCallBack); /* from lib/alias.c */
str[len] = c;
}
void
fixCallBack(user)
char *user;
{
NODE *node;
if (user[0] == '<') {
FILE *fi = fopen(user + 1, "r");
char *buf = malloc(256);
if (fi == NULL) {
ulog(-1, "Unable to open < file %s", user + 1);
return;
}
while (fgets(buf, 256, fi)) {
short i = 0;
short j;
while (buf[i] == ' ' || buf[i] == 9)
++i;
if (buf[i] == 0 || buf[i] == '\n')
continue;
for (j = i; buf[j] && buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9; ++j);
buf[j] = 0;
UserAliasList(buf, fixCallBack);
}
fclose(fi);
free(buf);
return;
}
ulog(-1, "Sendmail, Sending mail to %s", user);
if (user[0] == '\\')
++user;
node = malloc(sizeof(NODE) + strlen(user) + 1);
node->ln_Name = (char *)(node + 1);
strcpy(node->ln_Name, user);
AddTail(&XccList, node);
}
/*
* Integrates a header
*/
void
IntegrateHeader(hdr, len)
char *hdr;
short len;
{
if (hdr[len-1] == '\n') /* strip trailing newline */
hdr[len-1] = 0;
if (strncmp(hdr, "From:", 5) == 0) {
MakeNode(&FromList, hdr + 5);
return;
}
if (strncmp(hdr, "To:", 3) == 0) {
MakeNode(&ToList, hdr + 3);
return;
}
if (strncmp(hdr, "Cc:", 3) == 0) {
MakeNode(&CcList, hdr + 3);
return;
}
if (strncmp(hdr, "Bcc:", 4) == 0) {
MakeNode(&BccList, hdr + 4);
return;
}
if (strncmp(hdr, "Subject:", 8) == 0) {
MakeNode(&SubjList, hdr + 8);
return;
}
if (strncmp(hdr, "Received:", 9) == 0) {
MakeNode(&RecvList, hdr + 9);
return;
}
MakeNode(&HdrList, hdr);
}
/*
* Adds (personal info) to FromList based on passwd entry or, if
* that is not available, from the Config entry 'RealName'.
*/
void
FromFixup(list)
LIST *list;
{
char *wholeName = GetConfig("RealName", "Who Knows");
NODE *node;
NODE *nn;
LIST tmpList;
NewList(&tmpList);
while (node = RemHead(list)) {
/*
* FIXME. Fix getpwnam() and use pw_gecos entry.
*/
nn = malloc(sizeof(NODE) + strlen(node->ln_Name) + strlen(wholeName) + 16);
nn->ln_Name = (char *)(nn + 1);
sprintf(nn->ln_Name, "%s (%s)", node->ln_Name, wholeName);
free(node);
AddTail(&tmpList, nn);
}
while (node = RemHead(&tmpList))
AddTail(list, node);
}
/*
* Converts an unparsed list of names into a list of single address
* fields, removing any personal idents from the entries. These will
* be recombined after processing when the data file is written out.
*
* Also expands sendmail aliases (UULIB:Aliases) (HACK)
*/
void
ToFixup(list)
LIST *list;
{
NODE *node;
LIST tmpList;
NewList(&tmpList);
while (node = RemHead(list)) {
char *str = node->ln_Name;
char *ptr;
while (*str) { /* breakup fields by newline or comma */
for (ptr = str; *ptr && *ptr != '\n' && *ptr != ','; ++ptr);
MakeToAddrNode(&tmpList, str);
str = ptr;
while (*str == '\n' || *str == ',' || *str == ' ' || *str == 9)
++str;
}
free(node);
}
while (node = RemHead(&tmpList))
AddTail(list, node);
}
/*
* Extracts a single name / address (comma or newline delimited)
* field and creates a new node.
*/
void
MakeToAddrNode(list, str)
LIST *list;
char *str;
{
char *p1, *p2;
short ns = 0; /* non-whitespace encountered */
for (p1 = str; *p1 && *p1 != ',' && *p1 != '\n'; ++p1) {
if (*p1 == '(') { /* addr (name) OR (name) addr */
if (ns) { /* addr (name) */
MakeToFixNode(list, str, p1);
} else {
while (*p1 && *p1 != ',' && *p1 != '\n' && *p1 != ')')
++p1;
if (*p1 == ')') {
for (p2 = p1 + 1; *p2 && *p2 != ',' && *p2 != '\n'; ++p2);
MakeToFixNode(list, p1 + 1, p2);
}
}
return;
}
if (*p1 == '<') { /* <addr> */
for (p2 = p1 + 1; *p2 && *p2 != ',' && *p2 != '\n' && *p2 != '>'; ++p2);
if (*p2 == '>')
MakeToFixNode(list, p1 + 1, p2);
return;
}
if (*p1 != ' ' && *p1 != 9)
ns = 1;
}
MakeToFixNode(list, str, p1);
}
/*
* Send mail to <recipeant>
*
* -Local mail
* -Machine path (UUCP)
*/
FILE *
SendMailTo(list, fi)
LIST *list;
FILE *fi;
{
NODE *node;
for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ)
fi = OneMailTo(node->ln_Name, fi);
return(fi);
}
FILE *
OneMailTo(toaddr, rfi)
char *toaddr;
FILE *rfi;
{
short i;
char c;
static char Buf[256];
static char typeBuf[16];
static char classBuf[16];
static char addrBuf[128];
if (toaddr[0] == '|') /* pipe through command */
return(OneMailToPipe(toaddr + 1, rfi));
if (toaddr[0] == '>') /* copy to file */
return(OneMailToFile(toaddr + 1, rfi));
for (i = 0; c = toaddr[i]; ++i) {
if (c == '!' || c == '%' || c == '@' || c == ':')
break;
}
if (c == 0) /* local name */
return(OneMailToUser(toaddr, rfi));
/*
* Non-Local mail
*/
i = ParseAddress(toaddr, Buf, strlen(toaddr));
if (DomainLookup(Buf, strlen(Buf), typeBuf, classBuf, addrBuf)) {
printf("type %s class %s addr %s\n", typeBuf, classBuf, addrBuf);
printf("buf %s\n", Buf);
/*
* Note distinction between mail destination and mail forwarder.
* mail destination removes the first machine from the rmail line
* mail forwarder does NOT
*/
if (strcmpi(classBuf, "UU") == 0) {
if (strcmpi(typeBuf, "MD") == 0)
return(OneMailToUUCP(addrBuf, Buf + i + 1, rfi));
else
return(OneMailToUUCP(addrBuf, Buf, rfi));
} else {
ulog(-1, "Unsupported domain class: %s", classBuf);
printf("Unsupported domain class: %s\n", classBuf);
}
return(rfi);
} else {
ulog(-1, "Could not find domain for %s, no mail sent", Buf);
printf("Unable to send mail to %s\n", Buf);
return(rfi);
}
}
FILE *
OneMailToPipe(toaddr, rfi)
char *toaddr;
FILE *rfi;
{
FILE *fi;
char *ptr;
static long pos;
if (TempFileBuf[0] == 0) {
strcpy(TempFileBuf, TmpFileName("T:pipe"));
fi = fopen(TempFileBuf, "w");
if (fi == NULL) {
ulog(-1, "Unable to open temp file %s for command: %s", TempFileBuf, toaddr);
return(rfi);
}
DumpHeaderInfo(fi, RCVR_SENDMAIL, 0, 1);
pos = ftell(fi);
while (fgets(ScrBuf, sizeof(ScrBuf), rfi))
fputs(ScrBuf, fi);
fclose(fi);
}
strcpy(ScrBuf, toaddr);
ptr = toaddr;
if (strncmpi(toaddr, "run", 3) == 0) {
ptr += 3;
while (*ptr == ' ' || *ptr == 9)
++ptr;
}
while (*ptr && *ptr != ' ' && *ptr != 9)
++ptr;
if (*ptr == 0)
strcat(ScrBuf, " ");
sprintf(ScrBuf + (ptr - toaddr + 1), "<%s %s", TempFileBuf, ptr);
if (Execute(ScrBuf, NULL, NULL) == 0)
ulog(-1, "Couldn't execute %s", ScrBuf);
fi = fopen(TempFileBuf, "r");
if (fi) {
if (rfi != stdin)
fclose(rfi);
rfi = fi;
fseek(rfi, pos, 0);
} else {
ulog(-1, "Couldn't reopen temp '%s', mail failed!", TempFileBuf);
rfi = stdin;
}
return(rfi);
}
FILE *
OneMailToUser(toaddr, rfi)
char *toaddr;
FILE *rfi;
{
sprintf(ScrBuf, "UUMAIL:%s", toaddr);
return(OneMailToFile(ScrBuf, rfi));
}
FILE *
OneMailToFile(tofile, rfi)
char *tofile;
FILE *rfi;
{
FILE *fo;
static char DataFile[128];
long pos;
strcpy(DataFile, tofile);
LockFile(DataFile);
fo = fopen(DataFile, "a");
if (fo == NULL) {
strcpy(DataFile, "T:MailOverflow");
fo = fopen(DataFile, "a");
if (fo)
ulog(-1, "Could not append to %s, appending to %s", tofile, DataFile);
else
ulog(-1, "Can't append to anywhere! (%s)", tofile);
}
if (fo) {
DumpHeaderInfo(fo, RCVR_SENDMAIL, 0, 1);
pos = ftell(fo);
if (ROpt) {
if (fgets(ScrBuf, sizeof(ScrBuf), rfi))
fputs(ScrBuf, fo);
}
while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) {
if (ScrBuf[0] == 'F' && strncmp(ScrBuf, "From ", 5) == 0)
strins(ScrBuf, " ");
fputs(ScrBuf, fo);
}
fclose(fo);
if (rfi != stdin)
fclose(rfi);
rfi = fopen(DataFile, "r");
fseek(rfi, pos, 0);
}
return(rfi);
}
FILE *
OneMailToUUCP(toaddr, skipaddr, rfi)
char *toaddr;
char *skipaddr;
FILE *rfi;
{
static char ExecFile[128];
static char XExecFile[128];
static char CommandFile[128];
static char DataFile[128];
static char DestNode[256];
/*static char ToAddr[256];*/
FILE *fi;
int seq;
long pos;
short i;
short ai;
/*
* If the destination node
*/
strcpy(DestNode, toaddr);
ai = -1;
for (i = 0; DestNode[i]; ++i) {
/*
* Remember index for additional paths
*/
if (DestNode[i] == '!') {
DestNode[i] = 0;
ai = i + 1;
break;
}
/*
* Cut off machine name at 7 chars and ignore any domain
* info.
*/
if (i == 7 || DestNode[i] == '.')
DestNode[i] = 0;
}
Seq = seq = GetSequence(4);
#define FOFF 8
sprintf(ExecFile, "UUSPOOL:D.%sX%04d", DestNode, seq++);
sprintf(XExecFile, "UUSPOOL:X.%sX%04d", DestNode, seq++);
sprintf(CommandFile,"UUSPOOL:C.%sA%04d", DestNode, seq++);
sprintf(DataFile, "UUSPOOL:D.%sB%04d", DestNode, seq);
LockFile(ExecFile);
LockFile(XExecFile);
LockFile(CommandFile);
LockFile(DataFile);
/*
* Note, cannot run uuxqt from sendmail as uuxqt may call
* sendmail!
*/
if (strncmp(DestNode, NodeName, 7) == 0)
fi = fopen(XExecFile, "w");
else
fi = fopen(ExecFile, "w");
if (fi == NULL)
goto fail;
fprintf(fi, "U %s\n", UserName);
fprintf(fi, "F %s\n", DataFile + FOFF);
fprintf(fi, "I %s\n", DataFile + FOFF);
if (ai >= 0)
fprintf(fi, "C rmail %s!%s\n", DestNode + ai, skipaddr);
else
fprintf(fi, "C rmail %s\n", skipaddr);
fclose(fi);
if (strncmp(DestNode, NodeName, 7)) {
fi = fopen(CommandFile, "w");
if (fi == NULL)
goto fail;
fprintf(fi, "S %s %s %s - %s 0666\n", DataFile + FOFF, DataFile + FOFF, UserName, DataFile + FOFF);
fprintf(fi, "S %s %s %s - %s 0666\n", ExecFile + FOFF, XExecFile + FOFF, UserName, ExecFile + FOFF);
fclose(fi);
}
fi = fopen(DataFile, "w");
if (fi == NULL)
goto fail;
DumpHeaderInfo(fi, RCVR_UUCP, 1, 0);
pos = ftell(fi);
if (ROpt) {
if (fgets(ScrBuf, sizeof(ScrBuf), rfi))
fputs(ScrBuf, fi);
}
while (fgets(ScrBuf, sizeof(ScrBuf), rfi)) {
if (ScrBuf[0] == 'F' && strncmp(ScrBuf, "From ", 5) == 0)
strins(ScrBuf, " ");
fputs(ScrBuf, fi);
}
fclose(fi);
if (rfi != stdin)
fclose(rfi);
fi = fopen(DataFile, "r");
fseek(fi, pos, 0);
return(fi);
fail:
puts("Fail");
return(rfi);
}
void
DumpHeaderInfo(fi, rcvr, resend, local)
FILE *fi;
{
char *source;
time_t t;
time(&t);
/*
* Write header info
*/
if (rcvr == RCVR_UUCP)
source = "AmigaUUCP";
else
source = "Sendmail";
if (ROpt) {
if (resend)
fprintf(fi, "%s %s remote from %s\n", FromLine, atime(&t), NodeName);
else
fprintf(fi, "%s %s\n", FromLine, atime(&t));
} else {
if (local)
fprintf(fi, "From %s %s\n", UserName, atime(&t));
else
fprintf(fi, "From %s %s remote from %s\n", UserName, atime(&t), NodeName);
}
fprintf(fi, "Received: by %s%s (0.44/0.44)\n\tid AA%05d; %s\n",
NodeName, DomainName, Seq, atime(&t)
);
DumpHeader(fi, "Received:", &RecvList);
if (ROpt == 0) {
time_t t2 = t + 3600 * GetHourOffset(TimeZoneName);
struct tm *ut;
if (FindHeader("Date:") == NULL)
fprintf(fi, "Date: %s\n", atime(&t));
ut = localtime(&t2);
fprintf(fi, "Message-Id: <%02d%02d%02d%02d%02d.AA%05d@%s%s>\n",
ut->tm_year % 100, ut->tm_mon + 1, ut->tm_mday, ut->tm_hour, ut->tm_min,
Seq, NodeName, DomainName
);
}
/*
* From:, To:, Cc:, Subject: (Bcc: never written to header),
* and any other header fields
*/
DumpHeader(fi, NULL, &HdrList);
DumpHeader(fi, "From:", &FromList);
DumpCombineHeader(fi, "To:", &ToList);
if (!EmptyList(&CcList))
DumpCombineHeader(fi, "Cc:", &CcList);
DumpHeader(fi, "Subject:", &SubjList);
fprintf(fi, "\n");
}
void
DumpHeader(fi, field, list)
FILE *fi;
char *field;
LIST *list;
{
NODE *node;
for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) {
if (field)
fprintf(fi, "%s %s\n", field, node->ln_Name);
else
fprintf(fi, "%s\n", node->ln_Name);
}
}
NODE *
FindHeader(field)
char *field;
{
NODE *node;
short len = strlen(field);
for (node = HdrList.lh_Head; node != (NODE *)&HdrList.lh_Tail; node = node->ln_Succ) {
if (strncmp(node->ln_Name, field, len) == 0)
return(node);
}
return(NULL);
}
void
DumpCombineHeader(fi, field, list)
FILE *fi;
char *field;
LIST *list;
{
NODE *node;
short ci = 0;
fprintf(fi, "%s ", field);
for (node = list->lh_Head; node != (NODE *)&list->lh_Tail; node = node->ln_Succ) {
if (ci && ci + strlen(node->ln_Name) > 70) {
fprintf(fi, ",\n\t");
ci = 0;
}
if (ci)
fprintf(fi, ", ");
fprintf(fi, "%s", node->ln_Name);
ci += strlen(node->ln_Name) + 2;
}
fprintf(fi, "\n");
}
char *
atime(pt)
time_t *pt;
{
static char buf[40];
static char *mo[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static char *dow[7] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
struct tm *ut = localtime(pt);
sprintf(buf, "%s, %d %s %02d %02d:%02d:%02d %s",
dow[ut->tm_wday], ut->tm_mday, mo[ut->tm_mon],
ut->tm_year % 100, ut->tm_hour, ut->tm_min, ut->tm_sec,
TimeZoneName
);
return(buf);
}
GetHourOffset(tz)
char *tz;
{
short i;
static struct {
char *Name;
short Hours;
} TZAry[] = {
"GMT", 0,
"UT", 0,
"PST", 8,
"MST", 7,
"CST", 6,
"EST", 5,
"AST", 4,
"PDT", 7,
"MDT", 6,
"CDT", 5,
"EDT", 4,
"ADT", 3,
NULL, 0
};
for (i = 0; TZAry[i].Name; ++i) {
if (strncmp(tz, TZAry[i].Name, 3) == 0)
return((int)TZAry[i].Hours);
}
ulog(-1, "Unknown Timezone: %s", tz);
printf("Unknown Timezone: %s", tz);
return(6);
}
void
PostPend(str, frend)
char *str;
{
char *ptr;
if (frend) {
ptr = str + strlen(str);
while (ptr > str && *ptr != ' ' && *ptr != 9) {
if (*ptr == '\n')
*ptr = 0;
--ptr;
}
str = ptr + 1;
}
for (ptr = str; *ptr && *ptr != ' ' && *ptr != 9 && *ptr != '\n'; ++ptr);
if (frend)
strcpy(ptr, "!");
else
strcpy(ptr, "");
for (ptr = FromLine + 5; *ptr && *ptr != ' ' && *ptr != 9; ++ptr);
strins(ptr, str);
}
EmptyList(list)
LIST *list;
{
if (list->lh_Head == (NODE *)&list->lh_Tail)
return(1);
return(0);
}